home *** CD-ROM | disk | FTP | other *** search
- Introduction
- ============
-
- OSLib is a set of functions and C headers to provide complete coverage of
- the RISC O S application programmer's interface in C. It provides access
- from C code to all RISC O S system calls ("SWI's") which is
-
- efficient: often, memory access is completely avoided;
- type-safe: every argument can be type-checked by the compiler;
- obvious: a SWI is called by the "obvious" syntax;
- complete: every SWI is covered;
- register-safe: hides (often idiosyncratic) register allocation;
- language-independent: although the headers are specific to C, the
- library is not - any A P C S-conformant language can call it.
-
- It also provides names for all the data structures and reason codes used by
- the A P I. Code that uses it is superior to similar code using _kernel_swi()
- or _swix(), both in terms of the compile-time checking that is available,
- and the size and speed of the code generated.
-
- In addition to the module files, there is also a file "types.h" which
- contains macros and types useful for any programme.
-
- This file explains how OSLib relates to the P R M descriptions of the
- SWI's in complete detail. It is best read in conjunction with the header
- files themselves.
-
- The OSLib Structuring Conventions
- === ===== =========== ===========
-
- Each header file provides
-
- function prototypes
- typedefs
- macros
-
- that completely specify the interface to a module. All symbols provided by
- "<module>.h" are of the form <module>_<name> (except some of the form
- <module><name>_<reason>). For functions, <name> is the name of the SWI,
- converted to lower-case, and with underscores inserted between each word:
-
- SWI Function
- --- --------
- OS_ReadLine os_read_line
- Wimp_CreateWindow wimp_create_window
-
- For typedefs, <name> is a sequence of words in lower-case, separated by
- underscores:
-
- Type Meaning
- ---- -------
- os_colour a palette entry value (&bbggrr00)
- wimp_window a window definition structure
-
- For macros, <name> is a sequence of words in upper-case, separated by
- underscores:
-
- Macro Meaning
- ----- -------
- os_MODEVAR_XEIG_FACTOR a value for os_read_mode_variable
- error_ESCAPE the error number of Escape (17)
- wimp_ICON_NAME_LIMIT the largest length of an icon name
-
- (all macros for maximum values end in _LIMIT). There is also a special set
- of macros provided for more convenient handling of structures with a
- variable number of trailing parts, as used for mode selectors or Wimp
- window definitions, for example:
-
- Macro Meaning
- ----- -------
- os_PALETTE (nc) Declarator for a palette with |nc| colours
- os_SIZEOF_PALETTE (nc) Size of that palette
- wimp_WINDOW (ni) Declarator for a window with |ni| icons
- wimp_SIZEOF_WINDOW (ni) Size of the complete window definition
-
- Furthermore, every SWI number and SWI reason code has a macro defined of the
- form <Module>_<Name> (in mixed case form):
-
- Macro Value
- ----- -----
- OS_WriteC 0
- Font_FindFont 0x40081
-
- These are rarely needed.
-
- In fact, for each SWI, two functions are provided: one has a name
- prefixed with an x and returns a value of type |os_error *|, which is non-
- null if the SWI fails; the other does not start with an x, and never returns
- an error: if the SWI fails, a signal (|SIGOSERROR|, number 10) is raised,
- and may be caught by installing a signal handler for it. The non-x form can
- therefore return a result, instead of having to write to an output argument:
- for example, the SWI Wimp_CreateWindow can be called by either of the
- prototypes
-
- os_error *xwimp_create_window (wimp_window *window, wimp_w *w);
- wimp_w wimp_create_window (wimp_window *window);
-
- They have exactly the same effect if all goes well, but if there is an
- error, the first just returns it, while the other raises |SIGOSERROR| and
- does not return at all. (If you use the second, the signal handler for
- |SIGOSERROR| can use _kernel_last_oserror() to find out what the error was.)
-
- The function prototype is derived from the SWI description in the
- following way. Arguments corresponding to input registers appear first in
- order in the argument list, followed by the addresses of variables in which
- the output registers' values are to be written. If an output register value
- is not needed, a null pointer can be written in that position. (Since |int|
- and all pointer types are 32 bits on the ARM, it doesn't matter which type
- of null pointer is used.)
-
- Most of the types are fully defined: e g, a |wimp_window| is a structure
- type with all the fields defined with the right type and name to be passed to
- any SWI that uses it. Some types are "abstract," however: they are exported
- by a module, but the internal structure is not accessible to its clients.
- The best way of representing this in C is by an unspecified pointer type: a
- definition of the form
-
- typedef struct <tag> *<type>
-
- where the structure is never defined in full. Doing this allows the compiler
- to typecheck arguments of these types. The full list of such "abstract
- types" is
-
- buffer_b
- buffer_internal_id
- colourpicker_d
- devicefs_d
- devicefs_s
- devicefs_h
- dma_c
- dma_tag
- econet_rx_cb
- econet_tx_cb
- os_mode
- osfscontrol_id
- osspriteop_id
- wimp_t
- wimp_w
-
- In addition, various modules use values from name spaces that are
- centrally allocated by Acorn. These are: |error_|, |message_|, |...v|,
- |event_| and |upcall_|, and they each have their own prefix. They correspond
- to error numbers, WIMP message numbers, vectors (which are reason codes for
- OS_CallAVector), service calls (reason codes for OS_ServiceCall), events
- (reason codes for OS_GenerateEvent) and upcalls (reason codes for
- OS_UpCall), respectively. In cases where name clashes are possible, the
- module name occurs in the <name> part:
-
- error_BUFFER_MANAGER_BUFFER_TOO_SMALL
- error_COLOUR_TRANS_BAD_DEPTH
-
- (Vectors are represented by a suffix, |...v|, rather than a prefix, since
- this is familiar.) These rules mean that if you are writing code for RISC
- O S, and you avoid
-
- (a) all names that start with the name <module> of any
- "<module>.h" you need to include;
-
- (b) all names that start with |error|, |message|, |event|
- or |upcall|, or end with |v|;
-
- then no names clashes will occur.
-
- Types.h
- =======
-
- All OSLib header files ensure that "types.h" is included. This file
- contains various types, macros for value and function-like macros that are
- generally useful. They are described here:
-
- Types
- -----
-
- |bits|: Used for flags values and masks, normally consisting of fields of
- 1 or more bits. Macros are normally provided to help with getting these
- fields out: for a 1-bit field, a macro |X| such that
-
- To Use
- -- ---
- Read the field (v & X) != NONE
- Write a 0 v &= ~X
- Write a 1 v |= X
-
- and for a multi-bit field, macros X and X_SHIFT such that
-
- To Use
- -- ---
- Read the field (v & X) >> X_SHIFT
- Write a value |w| v = (v & ~X) | w << X_SHIFT.
-
- |bool|: Used for a truth value.
-
- |byte|: Used for a single byte value, as an alternative to |char| when the
- values are just data, rather than being characters as such. It is an unsigned
- type, which means that 2 instructions can be saved in P C C mode, where
- |char| is signed and must be sign-extended.
-
- Constant-like macros
- ------------- ------
-
- |NULL|: the usual C null pointer constant.
-
- |FALSE|: value of type |bool| representing falsehood.
-
- |TRUE|: value of type |bool| representing truth.
-
- |NONE|: value of type |bits| with all bits clear.
-
- |ALL|: value of type |bits| with all bits set.
-
- |SKIP|: may be used as a "don't care" value for |int|, pointers,
- |bits|.
-
- |SIG_LIMIT|: largest signal number + 1.
-
- |_C|, |_Z|, |_N|, |_V|: masks for the flags in the P S R.
-
- |DEC_WIDTH|: the length of INT_MAX (2147483647) printed with %d.
-
- |SHORT_DEC_WIDTH|: the length of SHRT_MAX (32767) printed with %hd.
-
- |LONG_DEC_WIDTH|: the length of LONG_MAX (2147483647) printed with %ld.
-
- |OCT_WIDTH|: the length of UINT_MAX (37777777777) printed with %o.
-
- |SHORT_OCT_WIDTH|: the length of USHRT_MAX (177777) printed with %ho.
-
- |LONG_OCT_WIDTH|: the length of ULONG_MAX (37777777777) printed with %lo.
-
- |UNSIGNED_WIDTH|: the length of UINT_MAX (4294967295) printed with %u.
-
- |SHORT_UNSIGNED_WIDTH|: the length of USHRT_MAX (65535) printed with %hu.
-
- |LONG_UNSIGNED_WIDTH|: the length of ULONG_MAX (4294967295) printed with
- %lu.
-
- |HEX_WIDTH|: the length of UINT_MAX (FFFFFFFF) printed with %x.
-
- |SHORT_HEX_WIDTH|: the length of USHRT_MAX (FFFF) printed with %hx.
-
- |LONG_HEX_WIDTH|: the length of ULONG_MAX (FFFFFFFF) printed with %lx.
-
- |FLT_WIDTH|: the precision needed to distinguish 1 + FLT_EPSILON from 1
- printed with %f.
-
- |DBL_WIDTH|: the precision needed to distinguish 1 + DBL_EPSILON from 1
- printed with %f.
-
- |LDBL_WIDTH|: the precision needed to distinguish 1 + LDBL_EPSILON from 1
- printed with %Lf.
-
- |FLT_EXP_WIDTH|: the length of the exponent of FLT_MAX printed with %f.
-
- |DBL_EXP_WIDTH|: the length of the exponent of DBL_MAX printed with %f.
-
- |LDBL_EXP_WIDTH|: the length of the exponent of LDBL_MAX printed with %Lf.
-
- |ERROR|: intended as an "out-of-band" value to be returned by functions
- like fgetc() which return |EOF| on end-of-file. |ERROR| may be used to
- indicate an error condition.
-
- |UNKNOWN|: used to declare (but not define) arrays of unknown size, as
- an argument to the type macros (e g, wimp_WINDOW()) described above.
-
- Function-like macros
- ------------- ------
-
- |WHETHER|: convert a bool value to a string.
-
- |MAX|: larger of two values.
-
- |MIN|: smaller of two values.
-
- |MAXAB|: larger of two values and assign.
-
- |MINAB|: smaller of two values and assign.
-
- |ABS|: absolute value.
-
- |SGN|: signum.
-
- |DIM|: positive difference.
-
- |SQR|: square.
-
- |RATIO|: integer division, rounding to nearer.
-
- |BOOL|: convert an integer to bool.
-
- |UCHAR|: character corresponding to a digit (upper case preferred).
-
- |LCHAR|: ditto, lower case.
-
- |BINEXP|: 2 to the power of.
-
- |ISDIGIT|: a digit?
-
- |ISXDIGIT|: a hex digit?
-
- |DIGIT|: if a digit, then which, else undefined.
-
- |XDIGIT|: if a hex digit, then which, else undefined.
-
- |DBLEQ|: equality for floating-point numbers (requires a tolerance)
-
- |BIT|: the bit at an offset from a pointer.
-
- |SET|: set a bit at an offset from a pointer.
-
- |CLR|: clear a bit at an offset from a pointer.
-
- |CLEAR|: clear a string.
-
- |EMPTY|: is a string empty?
-
- |NCOPY|: copy at most a given number of characters from a string, and
- terminate it.
-
- |STR_|: helper macro for STR.
-
- |STR|: convert a macro to source string.
-
- |COUNT|: number of elements in an array.
-
- |ALIGN|: round an integer up to the next multiple of 4.
-
- |WORD|: assembles an |int| from an unaligned byte pointer.
-
- |SHORT|: assembles a |short| from an unaligned byte pointer.
-
- Macros that "change the language"
- ------ ---- ------- --- ---------
-
- (Not everyone likes using these!)
-
- |AS| is the same as |.|, but can be used to let the reader know that the
- left operand is a |union| rather than a |struct|.
-
- |ASREF| is the same as |->|, but can be used to let the reader know that
- the left operand is a |union *| rather than a |struct *|.
-
- |_| is the same as |,|, but if used to separate the arguments of a macro
- call is not recognised as a comma by the preprocessor. This lets you write
- macros with variable numbers of arguments.
-
- Macros to suppress compiler warnings
- ------ -- -------- -------- --------
-
- |NOT_USED|: Suppress "variable not used" message.
-
- |UNSET|: Suppress "variable may be used before being set" message.
-
- Additional Structuring Rules
- ========== =========== =====
-
- The design aims listed in paragraph 1 are not completely compatible. In
- order to provide type-safety, it is necessary to provide multiple veneers
- for some SWI's. These fall into two classes: where a SWI has multiple reason
- codes, each reason code is provided with a separate function; and where a
- SWI has two or more different variants, each variant is provided with its
- own function.
-
- Reason codes
- ------ -----
-
- Many SWI's have several reason codes each of which has its own distinct
- purpose and register usage. In this case, each reason code is provided with
- its own function. (SWI's with a "reason code" parameter which does not
- affect the interpretation of the other parameters are not treated like this:
- instead, the reason codes are just provided as macros.) In some cases, one
- reason code may itself have different sub-reason codes. The complete list of
- SWI's divided into separate functions in this way is:
-
- ADFS_DiscOp
- ADFS_PowerControl
- ADFS_MiscOp
- ColourTrans_MiscOp
- DeviceFS_CallDevice
- FileCore_DiscOp
- FileCore_MiscOp
- FilerAction_SendStartOperation
- IIC_Control
- NetPrint_ListServers
- OS_Args*
- OS_Byte*
- OS_ClaimScreenMemory
- OS_DynamicArea
- OS_File*
- OS_Find*
- OS_FSControl*
- OS_GBPB*
- OS_Heap*
- OS_Memory (RO3.5)
- OS_Module*
- OS_Pointer (RO3.5)
- OS_ReadSysInfo*
- OS_ScreenMode (RO3.5)
- OS_SerialOp*
- OS_SpriteOp*
- OS_Word*
- OSWord_ReadClock
- OSWord_WriteClock
- OSWord_Pointer
- Parallel_Op
- PDriver_MiscOp
- PDriver_MiscOpForDriver
- RamFS_DiscOp
- ScreenModes_ReadInfo (RO3.5)
- Sound_InstallVoice
- TaskWindow_TaskInfo
- Wimp_ClaimFreeMemory
- Wimp_SpriteOp*
- Wimp_ReadSysInfo*
-
- In every case, the functions that are derived from the SWI use the
- entirety of the SWI name (with no underscore) as their prefix. Those marked
- '*' have their own header file, with that name. Others share the header file
- with the SWI. Also,
-
- Service_International
-
- has its own reason codes with the prefix |serviceinternational_|, residing
- in "serviceinternational.h";
-
- KeyV
- PaletteV
- PointerV
-
- have reason codes in "os.h", and
-
- OS_UpCall 3
-
- has reason codes with prefixes |upcallfile_|, |upcallfscontrol_| and
- |upcallfind_| in "osfile.h", "osfscontrol.h" and "osfind.h" respectively.
-
- Where a header file name is longer than 10 characters, the full name
- should be used in |#include| statements. FileCore-based filing systems will
- truncate the file name to 10 characters, if the *Configure option 'Truncate'
- is 'On' (which is recommended). This means that, for example, the line
- |#include "messagetrans.h"| will work on all filing systems: FileCore-based
- ones will convert the name to "messagetra.h." This applies to
-
- ColourTrans
- DragASprite
- FilerAction
- MessageTrans
- OSFSControl
- OSReadSysInfo
- ScreenBlanker
- ScreenModes
- ServiceInternational
- SharedCLibrary
- TaskManager
- WimpReadSysInfo
- WimpSpriteOp
-
- OS_WriteI might be considered to have a reason code (the character to be
- written), but since it is part of the SWI number, each character has a
- separate function. This is not worthwhile for printing characters, but for
- other VDU codes gives useful calls like os_clg() (to clear the graphics
- window), os_bell() (to ring the bell) etc. (The complete list is os_null,
- os_char_to_printer, os_printer_on, os_printer_off, os_split_cursors,
- os_join_cursors, os_vdu_on, os_bell, os_backspace, os_tab, os_line_feed,
- os_vertical_tab, os_cls, os_return, os_page_mode_on, os_page_mode_off,
- os_clg, os_set_text_colour, os_set_gcol, os_set_palette, os_reset_colours,
- os_vdu_off, os_set_mode, os_misc, os_set_graphics_window, os_plot_vdu,
- os_reset_windows, os_escape, os_set_text_window, os_set_graphics_origin,
- os_home_text_cursor, os_set_text_cursor, os_space, os_delete.)
-
- Many of the reason codes of OS_CallAVector have been omitted, namely,
- those where there are many sub-reason codes, and the purpose of the vector
- is exactly duplicated by a SWI or SWI's. So you will not find findv_-
- openin() (to call sub-reason code OSFind_OpenIn of reason code FindV of
- SWI OS_CallAVector), because it is identical in purpose to osfind_openin().
- If there are reason codes but no SWI, the reason codes do have functions
- provided (e g, PaletteV), and if there are no reason codes, the function is
- provided even if it does duplicate a SWI - for example, you can call
- os_writec() or wrchv() with the same effect (unless you are implementing
- them, of course). This is all just to keep the library size down. (Since
- calls to OS_GenerateEvent and OS_UpCall are already distributed through many
- files, vectored versions of them would have to be distributed in the same
- way.)
-
- Lastly, calls provided by FileSwitch are in "fileswitch.h", unless they
- have their own header. These are: os_bget(), bgetv(), os_bput(), bputv(),
- service_start_up_fs(), service_fs_redeclare(), service_close_file(). (The
- separate headers are "osargs.h," osfile.h," osfind.h," osfscontrol.h,"
- "osgbpb.h.")
-
- Variants
- --------
-
- Some SWI's have two or more different functions that call them, because
- they have two different calling conventions that cannot be easily captured
- using C's type system. These are listed below.
-
- Colourtrans_select_table_for_sprite() (variant of colourtrans_select_-
- table()) takes an |osspriteop_area *| and an |osspriteop_id|, rather than
- an |os_mode| and an |os_palette *|, as its first two arguments. The same
- applies to colourtrans_generate_table_for_sprite() (variant of colourtrans_-
- generate_table()) and colourtrans_select_gcol_table_for_sprite() (variant of
- colourtrans_select_gcol_table()).
-
- Filecorediscop_floppy_read_track(), filecorediscop_hard_disc_read_id()
- (variants of FileCore_DiscOp 3) exist only because the purpose of this SWI
- is very different depending on whether the target is a hard disc or a
- floppy. The same variation occurs again in filing systems that provide a
- SWI to call this one (ADFS and RamFS).
-
- Filecorediscop_write_track(), filecorediscop_format_track() (variants of
- FileCore_DiscOp 4) also have different purposes, and need different types
- and numbers of arguments.
-
- Font_read_identifier() (variant of font_read_defn()) is provided because
- of the different purposes depending on the "magic number" 'FULL.'
-
- Font_set_true_palette() (variant of font_set_palette()) is provided
- because of the different purposes depending on the "magic number" 'True.'
-
- Event_input_buffer_full_block_op() (variant of event_input_buffer_-
- full()) is provided because of the different arguments, and to avoid
- setting bit 31 of an address in C.
-
- Insv_block() (variant of insv()) is provided because of different
- argument requirements. (Neither remv() nor cnpv() are implemented yet,
- however, because uniquely they have to set up P S R flags on entry.)
-
- Os_read_colour() (variant of os_set_colour()) is provided so that os_set_-
- colour() can remain backwards-compatible (RO3.5).
-
- Os_read_line_given_echo(), os_read_line_suppress_invalid(), os_read_-
- line_given_echo_suppress_invalid() are variants of os_read_line(), provided
- to avoid setting bits 30, 31 of an address in C, and because of the need
- for an extra argument for 2 of them.
-
- Osargs_read_ptr(), osargs_read_temporary_fs() (variants of OS_Args 0)
- have different argument types and different purposes.
-
- Osfile_load() (variant of osfile_load_stamped()) is separate because no
- address need be specified to load a file with a load address: the load
- address itself is used. This also applies to osfile_load_path() (variant of
- osfile_load_stamped_path()), osfile_load_path_var() (variant of osfile_-
- load_stamped_path_var()) and osfile_load_no_path() (variant of osfile_load_-
- stamped_no_path()).
-
- Osspriteop_read_palette_size(), osspriteop_remove_palette(),
- osspriteop_create_palette() and osspriteop_create_true_palette() (variants
- of OS_SpriteOp 37) are provided because of the separate purposes of these
- entries.
-
- Squash_compress_return_sizes() (variant of squash_compress()) and
- squash_decompress_return_sizes() (variant of squash_decompress()) are
- provided because of the different purposes dependent on bit 3 of R0.
-
- Territory_read_symbols() is divided into 3 variants, territory_read_-
- boolean_symbols(), territory_read_integer_symbols() and territory_read_-
- string_symbols(), because different symbols have different types.
-
- Wimp_create_icon_relative() and wimp_create_icon_prioritised() (variants
- of wimp_create_icon()) exist because of the different purposes dependent on
- flags in a block, involving an extra |wimp_i| input argument.
-
- Wimp_get_window_info_header_only() (variant of wimp_get_window_info())
- is there so the caller does not have to set bit 0 of an address in C.
-
- Wimp_report_error_by_category() (variant of wimp_report_error() needing
- sprite area and name and extra buttons) exists because simple use of wimp_-
- report_error() has fewer arguments.
-
- Wimp_read_true_palette() (variant of wimp_read_palette()) provides new
- functionality invoked by a "magic number" 'TRUE'.
-
- Wimp_send_message_to_window() (variant of wimp_send_message()) takes a
- |wimp_w| and a |wimp_i| rather than a |wimp_t|, and returns a result (the
- task handle) which wimp_send_message() does not.
-
- Conclusion
- ==========
- Although there seem to be a lot of rules, that is because the RISC O S
- A P I is large. For normal application programming, most of it is not
- needed: applications don't normally deal with vectors, upcalls or service
- calls, for example, or do any direct access to disc structures. However,
- this is not ruled out. The C headers contain the complete description of
- exactly what each function does in terms of the mapping of the arguments to
- ARM registers, so no other documentation is needed.
-
- OSLib provides a very convenient interface to the RISC O S programmer,
- since all the facilities of the C compiler are available to catch errors
- and generate good code. It is conceptually very small, in that it is
- completely documented by this file. As a bonus, code written using it is
- smaller and faster than code written using other means.
-
- Disclaimer
- ==========
-
- OSLib is copyright © 1994 Acorn Computers Ltd. It is distributed in the
- hope that it will be useful, but without any warranty; without even the
- implied warranty of merchantability or fitness for a particular purpose.
-
- Fault reports and suggestions for improvement may be sent to the author,
- Jonathan Coxhead <jcoxhead@acorn.co.uk>. Although this is an Acorn address,
- OSLib is not an official Acorn product.
-